package de.tudresden.st.cbse.servlet;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import javax.naming.NamingException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import de.tudresden.st.cbse.calendar.Calendar;
import de.tudresden.st.cbse.calendar.RemoteCalendarManager;
import de.tudresden.st.cbse.calendar.appointment.Appointment;
import de.tudresden.st.cbse.calendar.appointment.AppointmentType;
import de.tudresden.st.cbse.calendar.share.ResultType;
import de.tudresden.st.cbse.calendar.share.ShareResult;
import de.tudresden.st.cbse.util.RemoteLookup;

@WebServlet("/appointment")
public class AppointmentServlet extends HttpServlet {
    private static final long serialVersionUID = 6114453400046783998L;

    private boolean validateAuthentication(HttpServletRequest req) {
        return req.getSession(true).getAttribute("currentSessionUser") != null;
    }

    private Date stringToDate(String date) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy HH:mm", Locale.GERMANY);
        return sdf.parse(date);
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        if (!validateAuthentication(req)) {
            resp.sendRedirect("index.jsp");
            return;
        }

        StringBuilder errorMsgBuilder = new StringBuilder();

        String title = req.getParameter("title");
        String note = req.getParameter("note");
        AppointmentType type = null;
        try {
            type = AppointmentType.valueOf(req.getParameter("type"));
        } catch (NullPointerException e) {
            errorMsgBuilder.append("Please set a type!<br />");

        }
        boolean isPrivate = "on".equals(req.getParameter("private"));

        if (title == "")
            errorMsgBuilder.append("Please specify a title!<br />");

        Date start = null;
        Date end = null;
        
        try {
            start = stringToDate(req.getParameter("start"));
            end = stringToDate(req.getParameter("end"));
        } catch (ParseException e) {
            errorMsgBuilder.append("Invalid date format. <br />Use dd.mm.yyyy hh:mm<br />");
        }
        
        if (start!= null && end != null && start.after(end)) {
            errorMsgBuilder.append("Start may not be after end!<br />");
        }

        if (!errorMsgBuilder.toString().isEmpty()) {
            req.setAttribute("errorMessage", errorMsgBuilder.toString());
            RequestDispatcher resultView = req.getRequestDispatcher("calendar.jsp");
            resultView.forward(req, resp);
            return;
        }

        Appointment appointment = new Appointment(title, note, start, end, isPrivate, type);
        String email = (String) req.getSession().getAttribute("currentSessionUser");
        
        try {
            RemoteCalendarManager calendarMgr = RemoteLookup.getCalendarManager();
            Calendar calendarOwn = calendarMgr.getCalendarForUser(email);

            ShareResult result = calendarOwn.check(appointment);
            if (result.getType() != ResultType.SUCCESSFUL) {
                req.setAttribute("shareresult", result);
                req.setAttribute("errorMessage", "The appointment overlaps with one that's already in your calendar!");
                RequestDispatcher resultView = req.getRequestDispatcher("calendar.jsp");
                resultView.forward(req, resp);
                return;
            }

            String shareWith = req.getParameter("share");
            if (shareWith != null && !shareWith.isEmpty()) {
                Calendar calendarOther = calendarMgr.getCalendarForUser(shareWith);
                if (calendarOther == null) {
                    req.setAttribute("errorMessage", "User "+shareWith+" does not exist!");
                    req.setAttribute("shareresult", new ShareResult(appointment, ResultType.NOSUCHUSER));
                    RequestDispatcher resultView = req.getRequestDispatcher("calendar.jsp");
                    resultView.forward(req, resp);
                    return;
                }

                result = calendarOther.check(appointment);
                if (result.getType() != ResultType.SUCCESSFUL) {
                    req.setAttribute("shareresult", result);
                    req.setAttribute("errorMessage", "The appointment overlaps with one that's already the calendar of "+shareWith+"!");
                    RequestDispatcher resultView = req.getRequestDispatcher("calendar.jsp");
                    resultView.forward(req, resp);
                    return;
                }

                calendarMgr.addAppointment(calendarOther, appointment);
            }

            calendarMgr.addAppointment(calendarOwn, appointment);
        } catch (NamingException e) {
            e.printStackTrace();
        }
        
        
        resp.sendRedirect("calendar");
    }
}
